<?php
declare (strict_types = 1);

namespace app\api\controller;

use app\api\model\Menu as MenuModel;
use app\api\model\Role as RoleModel;
use think\Request;
use think\response\Json;

/**
 * 系统管理控制器
 * 处理系统管理相关的接口（包括菜单管理）
 */
class SystemManage
{
    /**
     * 获取菜单列表（树形结构）
     * 前端接口：/systemManage/getMenuList
     * @param Request $request
     * @return Json
     */
    public function getMenuList(Request $request): Json
    {
        try {
            // 获取所有菜单并构建树形结构
            $tree = MenuModel::buildMenuTree();
            
            // 转换数据类型以匹配前端期望（确保数字字段转换为字符串）
            $tree = $this->formatMenuData($tree);
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => [
                    'records' => $tree,
                    'current' => 1,
                    'size' => count($tree),
                    'total' => count($tree),
                ]
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取菜单列表失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 格式化菜单数据，将字段转换为前端期望的类型
     * @param array $menus
     * @return array
     */
    private function formatMenuData(array $menus): array
    {
        return array_map(function($menu) {
            // 转换字段类型为字符串（前端TypeScript定义要求）
            if (isset($menu['menu_type'])) {
                $menu['menuType'] = (string)$menu['menu_type'];
            }
            if (isset($menu['icon_type'])) {
                $menu['iconType'] = (string)$menu['icon_type'];
            }
            if (isset($menu['status'])) {
                $menu['status'] = (string)$menu['status'];
            }
            
            // 添加驼峰命名字段映射（前端期望）
            if (isset($menu['parent_id'])) {
                $menu['parentId'] = $menu['parent_id'];
            }
            if (isset($menu['menu_name'])) {
                $menu['menuName'] = $menu['menu_name'];
            }
            if (isset($menu['route_name'])) {
                $menu['routeName'] = $menu['route_name'];
            }
            if (isset($menu['route_path'])) {
                $menu['routePath'] = $menu['route_path'];
            }
            if (isset($menu['i18n_key'])) {
                $menu['i18nKey'] = $menu['i18n_key'];
            }
            if (isset($menu['keep_alive'])) {
                $menu['keepAlive'] = $menu['keep_alive'];
            }
            if (isset($menu['hide_in_menu'])) {
                $menu['hideInMenu'] = $menu['hide_in_menu'];
            }
            if (isset($menu['active_menu'])) {
                $menu['activeMenu'] = $menu['active_menu'];
            }
            if (isset($menu['multi_tab'])) {
                $menu['multiTab'] = $menu['multi_tab'];
            }
            if (isset($menu['fixed_index_in_tab'])) {
                $menu['fixedIndexInTab'] = $menu['fixed_index_in_tab'];
            }
            if (isset($menu['query_params'])) {
                $menu['query'] = $menu['query_params'];
            }
            
            // 递归处理子菜单
            if (isset($menu['children']) && is_array($menu['children'])) {
                $menu['children'] = $this->formatMenuData($menu['children']);
            }
            
            return $menu;
        }, $menus);
    }
    
    /**
     * 获取菜单树（用于下拉选择）
     * 前端接口：/systemManage/getMenuTree
     * @return Json
     */
    public function getMenuTree(): Json
    {
        try {
            $tree = MenuModel::getMenuTreeForSelect();
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => $tree
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取菜单树失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 获取所有页面路由
     * 前端接口：/systemManage/getAllPages
     * @return Json
     */
    public function getAllPages(): Json
    {
        try {
            // 获取所有菜单类型为2（页面）的路由名称
            $pages = MenuModel::where('menu_type', '2')
                ->where('status', '1')
                ->column('route_name');
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => array_values(array_unique($pages))
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取所有页面失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 添加菜单
     * 前端接口：/systemManage/addMenu
     * @param Request $request
     * @return Json
     */
    public function addMenu(Request $request): Json
    {
        try {
            // 获取请求数据
            $data = $request->post();
            
            // 转换驼峰命名为蛇形命名（数据库字段）
            $dbData = $this->convertToSnakeCase($data);
            
            // 验证必填字段
            if (empty($dbData['menu_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '菜单名称不能为空',
                    'data' => null
                ], 400);
            }
            if (empty($dbData['route_name'])) {
                return json([
                    'code' => 400,
                    'msg' => '路由名称不能为空',
                    'data' => null
                ], 400);
            }
            if (empty($dbData['route_path'])) {
                return json([
                    'code' => 400,
                    'msg' => '路由路径不能为空',
                    'data' => null
                ], 400);
            }
            
            // 检查路由名称是否已存在
            $exists = MenuModel::where('route_name', $dbData['route_name'])->count();
            if ($exists > 0) {
                return json([
                    'code' => 400,
                    'msg' => '路由名称已存在',
                    'data' => null
                ], 400);
            }
            
            // 创建菜单
            $menu = MenuModel::create($dbData);
            
            return json([
                'code' => 0,
                'msg' => '添加成功',
                'data' => ['id' => $menu->id]
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '添加菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 更新菜单
     * 前端接口：/systemManage/updateMenu
     * @param Request $request
     * @return Json
     */
    public function updateMenu(Request $request): Json
    {
        try {
            // 获取请求数据
            $data = $request->post();
            
            // 验证ID
            if (empty($data['id'])) {
                return json([
                    'code' => 400,
                    'msg' => '菜单ID不能为空',
                    'data' => null
                ], 400);
            }
            
            // 转换驼峰命名为蛇形命名（数据库字段）
            $dbData = $this->convertToSnakeCase($data);
            $id = $dbData['id'];
            unset($dbData['id']); // 移除ID，不更新ID字段
            
            // 查找菜单
            $menu = MenuModel::find($id);
            if (!$menu) {
                return json([
                    'code' => 404,
                    'msg' => '菜单不存在',
                    'data' => null
                ], 404);
            }
            
            // 检查路由名称是否与其他菜单冲突
            if (!empty($dbData['route_name'])) {
                $exists = MenuModel::where('route_name', $dbData['route_name'])
                    ->where('id', '<>', $id)
                    ->count();
                if ($exists > 0) {
                    return json([
                        'code' => 400,
                        'msg' => '路由名称已存在',
                        'data' => null
                    ], 400);
                }
            }
            
            // 更新菜单
            $menu->save($dbData);
            
            return json([
                'code' => 0,
                'msg' => '更新成功',
                'data' => null
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '更新菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 删除菜单
     * 前端接口：/systemManage/deleteMenu
     * @param Request $request
     * @return Json
     */
    public function deleteMenu(Request $request): Json
    {
        try {
            $id = $request->post('id');
            
            if (empty($id)) {
                return json([
                    'code' => 400,
                    'msg' => '菜单ID不能为空',
                    'data' => null
                ], 400);
            }
            
            // 查找菜单
            $menu = MenuModel::find($id);
            if (!$menu) {
                return json([
                    'code' => 404,
                    'msg' => '菜单不存在',
                    'data' => null
                ], 404);
            }
            
            // 检查是否有子菜单
            $hasChildren = MenuModel::where('parent_id', $id)->count();
            if ($hasChildren > 0) {
                return json([
                    'code' => 400,
                    'msg' => '请先删除子菜单',
                    'data' => null
                ], 400);
            }
            
            // 删除菜单
            $menu->delete();
            
            return json([
                'code' => 0,
                'msg' => '删除成功',
                'data' => null
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '删除菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 批量删除菜单
     * 前端接口：/systemManage/batchDeleteMenu
     * @param Request $request
     * @return Json
     */
    public function batchDeleteMenu(Request $request): Json
    {
        try {
            $ids = $request->post('ids/a', []);
            
            if (empty($ids)) {
                return json([
                    'code' => 400,
                    'msg' => '请选择要删除的菜单',
                    'data' => null
                ], 400);
            }
            
            // 检查是否有子菜单
            $hasChildren = MenuModel::whereIn('parent_id', $ids)->count();
            if ($hasChildren > 0) {
                return json([
                    'code' => 400,
                    'msg' => '选中的菜单中有包含子菜单的项，请先删除子菜单',
                    'data' => null
                ], 400);
            }
            
            // 批量删除
            MenuModel::destroy($ids);
            
            return json([
                'code' => 0,
                'msg' => '删除成功',
                'data' => null
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '批量删除菜单失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
    
    /**
     * 将驼峰命名转换为蛇形命名（用于数据库操作）
     * @param array $data
     * @return array
     */
    private function convertToSnakeCase(array $data): array
    {
        $result = [];
        $mapping = [
            'menuType' => 'menu_type',
            'menuName' => 'menu_name',
            'routeName' => 'route_name',
            'routePath' => 'route_path',
            'parentId' => 'parent_id',
            'iconType' => 'icon_type',
            'i18nKey' => 'i18n_key',
            'keepAlive' => 'keep_alive',
            'hideInMenu' => 'hide_in_menu',
            'activeMenu' => 'active_menu',
            'multiTab' => 'multi_tab',
            'fixedIndexInTab' => 'fixed_index_in_tab',
            'query' => 'query_params',
        ];
        
        foreach ($data as $key => $value) {
            // 如果有映射，使用映射后的字段名
            $dbKey = $mapping[$key] ?? $key;
            
            // 处理query和buttons，JSON编码
            if (($dbKey === 'query_params' || $dbKey === 'buttons') && is_array($value)) {
                $result[$dbKey] = json_encode($value, JSON_UNESCAPED_UNICODE);
            } else {
                $result[$dbKey] = $value;
            }
        }
        
        return $result;
    }
    
    /**
     * 获取所有角色（用于下拉选择）
     * 前端接口：/systemManage/getAllRoles
     * @return Json
     */
    public function getAllRoles(): Json
    {
        try {
            // 获取所有角色
            $roles = RoleModel::select()->toArray();
            
            // 转换为前端期望的格式
            $result = array_map(function($role) {
                return [
                    'id' => $role['id'],
                    'roleName' => $role['name'],
                    'roleCode' => $role['role_code']
                ];
            }, $roles);
            
            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => $result
            ]);
            
        } catch (\Exception $e) {
            return json([
                'code' => 500,
                'msg' => '获取角色列表失败：' . $e->getMessage(),
                'data' => null
            ], 500);
        }
    }
}
